package com.yishan.gulimall.springsecurity.config;

import com.yishan.gulimall.springsecurity.filter.JwtAuthenticationFilter;
import com.yishan.gulimall.springsecurity.handler.AuthenticationAcceptHandler;
import com.yishan.gulimall.springsecurity.handler.AuthenticationImpl;
import com.yishan.gulimall.springsecurity.handler.SuccessLoginHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
//开启注解权限
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }


    /**
     * 获取AuthenticationManager对象,将他注入到spring容器中,用于后续的认证
     * @return
     * @throws Exception
     */
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    /**
     * 添加JWT过滤器
     */
    @Autowired
    private JwtAuthenticationFilter jwtAuthenticationFilter;

    /**
     * 认证失败处理器
     */
    @Autowired
    private AuthenticationImpl authenticationImpl;
    /**
     * 权限不足处理器
     */
    @Autowired
    private AuthenticationAcceptHandler authenticationAcceptHandler;

    @Autowired
    private SuccessLoginHandler successLoginHandler;


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 关闭csrf防护
        http
                .csrf().disable()
                //不通过session获取securityContext,因为在分布式系统中,session不共享,同时域名不同,session也不能共享
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                //允许匿名访问接口
                .antMatchers("/user/login").anonymous()
                //其他所有请求需要身份认证
                .anyRequest().authenticated();
        //添加JWT过滤器
        http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
        //认证失败处理器
        http.exceptionHandling().authenticationEntryPoint(authenticationImpl);
        //权限不足处理器
        http.exceptionHandling().accessDeniedHandler(authenticationAcceptHandler);
        //跨域配置
        http.cors();
        //认证成功处理器,这个地方可以要,也可以在登录的时候就进行处理,不需要在这里配置
        http.formLogin().successHandler(successLoginHandler);
    }
}
